package com.lovezy.platform.common.extend;

import com.lovezy.platform.common.extend.mapper.MemberExtendMapper;
import com.lovezy.platform.common.extend.model.MemberExtend;
import com.lovezy.platform.core.cache.Cache;
import com.lovezy.platform.core.codec.CodecUtil;
import com.lovezy.platform.core.exception.ServiceException;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Objects;

import static com.lovezy.platform.core.jwt.JwtUtil.createToken;

/**
 * Created by jin on 2017/12/17.
 */
@Service
public class ExtendService {

    private final Object createExtendLock = new Object();

    @Autowired
    private MemberExtendMapper memberExtendMapper;

    @Autowired
    private Cache cache;

    public String modifyToken(String mid) {
        MemberExtend memberExtend = findOrCreateExtend(mid);
        String token = CodecUtil.uuid();
        memberExtend.setToken(token);
        memberExtendMapper.updateByPrimaryKeySelective(memberExtend);
        saveInCache(memberExtend);
        return token;
    }

    public String refreshToken(String mid) {
        String tokenId = findTokenId(mid);
        return createToken(mid, tokenId);
    }

    private String findTokenId(String mid) {
        MemberExtend extend = findOrCreateExtend(mid);
        return extend.getToken();
    }

    public Boolean validToken(String mid, String token) {
        if (!StringUtils.hasText(token)) {
            return false;
        }
        MemberExtend memberExtend = findOrCreateExtend(mid);
        String token1 = memberExtend.getToken();
        return Objects.equals(token, token1);
    }

    public void registerDevice(String mid, String clientId) {
        if (!StringUtils.hasText(clientId)) {
            throw new ServiceException("初始化推送失败，ID为空");
        }
        MemberExtend memberExtend = findOrCreateExtend(mid);
        memberExtend.setClientId(clientId);
        memberExtendMapper.updateByPrimaryKeySelective(memberExtend);
        saveInCache(memberExtend);
    }

    @Nullable
    public String getDeviceId(String mid) {
        MemberExtend extend = findOrCreateExtend(mid);
        return extend.getClientId();
    }

    private MemberExtend findOrCreateExtend(String mid) {
        MemberExtend extend = getInCache(mid);
        if (extend == null) {
            synchronized (createExtendLock) {
                extend = memberExtendMapper.selectByPrimaryKey(mid);
                if (extend == null) {
                    extend = new MemberExtend();
                    extend.setMemberId(mid);
                    memberExtendMapper.insert(extend);
                }

            }
        }
        saveInCache(extend);
        return extend;
    }

    private void saveInCache(MemberExtend extend) {
        String memberId = extend.getMemberId();
        cache.put(getCacheKey(memberId), extend);
    }

    private MemberExtend getInCache(String mid) {
        String key = getCacheKey(mid);
        return cache.get(key, () -> memberExtendMapper.selectByPrimaryKey(mid));
    }

    private String getCacheKey(String mid) {
        return MemberExtend.class.getName() + "_" + mid;
    }


}
